﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data;

namespace DataAccess
{
    public class ControllerTecnico
    {
        #region ATRIBUTOS

        private SqlConnection conexion = DBConnection.getInstancia().getConnection();
        private static ControllerTecnico unConTec;

        #endregion
        
        #region SINGLETON

        public static ControllerTecnico getInstancia()
        {
            if(unConTec == null)
            {
                unConTec = new ControllerTecnico();
            }
            return unConTec;
        }

        #endregion

        #region CONSTRUCTORES

        private ControllerTecnico()
        {}

        #endregion

        #region METODOS

        //Alta de nuevo Tecnico.
        public void insertTecnico(Int32 pNro, string pNom, string pAp, string pTel, string pInt, string pMail, string pSec)
        {
            try
            {
                //Abrimos la conexion. 
                conexion.Open();
                //Declaramos la transaccion.
                SqlTransaction myTrans = conexion.BeginTransaction(IsolationLevel.Serializable);
                //Creamos el comando.
                SqlCommand myComm = conexion.CreateCommand();
                //Le asignamos la transaccion a la propiedad Transaction del comando creado.
                myComm.Transaction = myTrans;
                try
                {
                    //Insertamos en la tabla "personas".
                    myComm.CommandText = "INSERT INTO personas(pernrofuncionario, pernombre, perapellido, pertelefono, perinterno, permail, perseccion) VALUES (@pNro, @pNom, @pAp, @pTel, @pInt, @pMail, @pSec);";
                    myComm.Parameters.AddWithValue("pNro", pNro);
                    myComm.Parameters.AddWithValue("pNom", truncar(pNom, 29));
                    myComm.Parameters.AddWithValue("pAp", truncar(pAp, 29));
                    myComm.Parameters.AddWithValue("pTel", truncar(pTel, 29));
                    myComm.Parameters.AddWithValue("pInt", truncar(pInt, 19));
                    myComm.Parameters.AddWithValue("pMail", truncar(pMail, 49));
                    myComm.Parameters.AddWithValue("pSec", truncar(pSec, 49));
                    //Ejecutamos el comando.
                    myComm.ExecuteNonQuery();
                    //Insertamos en la tabla tecnicos.
                    myComm.CommandText = "INSERT INTO tecnicos(tecnrofuncionario) VALUES (@pNroTec);";
                    myComm.Parameters.AddWithValue("pNroTec", pNro);
                    //Ejecutamos el comando.
                    myComm.ExecuteNonQuery();
                    //Hacemos el commit.
                    myTrans.Commit();
                }
                catch (SqlException e)
                {
                    try
                    {
                        //Hacemos el rollback.
                        myTrans.Rollback();

                    }
                    catch (SqlException ex)
                    {
                        throw ex;
                    }
                }

            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                //Cerramos la conexion.
                conexion.Close();
            }
        }

        

        //Dar Tecnico por Nro. de funcionario.
        public DataTable getTecnicoByNro(Int32 pNro)
        {
            return ControllerPersona.getInstancia().getFuncionarioByNro(pNro, "tecnicos", "tecnrofuncionario");
        }

        //Dar Tecnico por Nombre de funcionario.
        public DataTable getTecnicoByName(string pNom, string pAp)
        {
            return ControllerPersona.getInstancia().getFuncionarioByName(pNom, pAp, "tecnicos", "tecnrofuncionario");
        }

        //Dar Tecnico por estado.
        public DataTable getTecnicosByEstado(bool pEstado)
        {
            return ControllerPersona.getInstancia().getFuncionariosActivos(pEstado, "tecnrofuncionario", "tecnicos");
        }

        //Dar lista de tecnicos y cantidad de solicitudes asignadas, ordenada por estas ultimas en orden descendente.
        public DataTable getTecnicosByCantSol()
        {
            //Consulta.
            string sql = "SELECT t.Id AS Nro, t.Nombre AS Tecnico, (CASE WHEN x.cant IS NULL THEN 0 ELSE x.cant END) AS Cantidad FROM (SELECT p.pernrofuncionario AS Id, CONCAT(p.pernombre, ' ', p.perapellido) AS Nombre FROM personas AS p WHERE p.peractivo = 1 AND p.pernrofuncionario IN (SELECT tecnrofuncionario FROM tecnicos)) AS t LEFT JOIN (SELECT s.solnrotecnico AS nrotecnico, COUNT(*) AS cant FROM solicitudes AS s GROUP BY s.solnrotecnico) AS x ON t.Id = x.nrotecnico ORDER BY Cantidad, Tecnico;";
            //Se crea el datatable.
            DataTable myDt = new DataTable();
            //Se crea el comando.
            SqlCommand myComm = new SqlCommand(sql, conexion);
            //Se crea el data adapter para llenar la tabla y se le pasa el comando como parametro.
            SqlDataAdapter myDa = new SqlDataAdapter(myComm);
            try
            {
                //Se abre la conexion.
                conexion.Open();
                //Se llena la tabla con el data adapter.
                myDa.Fill(myDt);
            }
            catch (Exception ex)
            {
                throw new Exception("Error al buscar tecnicos por cantidad de solicitudes: " + ex.Message);
            }
            finally
            {
                //Se cierra la conexion.
                conexion.Close();
            }
            //Se devuelve el data table.
            return myDt;
        }
        string truncar(string unSt, int maxLength)
        {
            return unSt.Length <= maxLength ? unSt : unSt.Substring(0, maxLength);
        } 
        #endregion
    }
}
